#!/bin/bash

source ../scripts/common.sh

export USER_GROUP=www
export USER_NAME=php

#编译安装PHP

LIB_MEMCACHED_VER=1.0.18
LIB_MEMCACHED_MD5SUM=b3958716b4e53ddc5992e6c49d97e819

PHP_VERSION=8.1.13
PHP_MD5SUM=43302de3d2c064f2f23c9693a2f17aeb


PHP_MEMCACHED_VER=3.1.5
PHP_MEMCACHED_MD5SUM=8db24eae99a73b605dbee7536d960e5a


PHP_REDIS_VER=5.3.4
PHP_REDIS_MD5SUM=c24202546809e0cc36652897caa3d21c

export PHP_OPENSSL_DIR=yes

# Debian8 下安装PHP8 需要
OPENSSL_OLD_VERSION=1.0.2u
OPENSSL_OLD_VERSION_MD5SUM=cdc2638f789ecc2db2c91488265686c1

ONIG_VERSION=6.9.7
ONIG_VERSION_REV=.1
ONIG_MD5SUM=d39409a103dcd44425e37b88d642f22c

LIBZIP_VERSION=1.8.0
LIBZIP_MD5SUM=c0448fb7be85bc1caa87bc2fe5ab5ff8

PHP8_BASE_PATH=/usr/local/php
read -p "请输入PHP8的安装路径($PHP8_BASE_PATH):"  PHP8_BASE_PATH

# 确定PHP8 安装路径
if [ -n $PHP8_BASE_PATH ]; then
PHP8_BASE_PATH=/usr/local/php
fi

echo "PHP将被安装到: $PHP8_BASE_PATH";


egrep "^${USER_GROUP}:" /etc/group >& /dev/null  
if [ $? -ne 0 ]; then
	groupadd $USER_GROUP
fi

egrep "^${USER_GROUP}.*[:,]${USER_NAME}$" /etc/group >& /dev/null  
if [ $? -ne 0 ]; then
	useradd -G $USER_GROUP -M -s /usr/sbin/nologin $USER_NAME
fi

if [ $OS_TYPE = "Centos" ]; then
	yum install -y libxml2-devel gcc-c++ autoconf make cmake libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel \
	libxml2 libxml2-devel zlib zlib-devel unzip zip libzip glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel \
	curl curl-devel libcurl-devel ncurses openssl-devel libXpm-devel libX11-devel gd-devel gmp-devel \
	readline-devel libxslt-devel expat-devel xmlrpc-c libicu-devel sqlite-devel wget;
elif [ $OS_TYPE = "Debian" ]; then
	apt install -y make cmake g++ libiconv-hook-dev libmcrypt-dev libmysqlclient-dev libcurl4-openssl-dev libjpeg-dev libfreetype6-dev libssl-dev
	apt install -y autoconf libxml2-dev libzip-dev libbison-dev libwebp-dev pkg-config
	apt install -y libtool automake flex bison libsasl2-dev shtool libmemcached-dev libsqlite3-dev libonig-dev libsodium-dev
	apt install -y re2c
else
	echo -e "\033[31m[ERROR]\033[0m 目前只支持 Debian 和 Centos"
	exit 0;
fi


#下载源码，用的是美国镜像
if [ $OS_TYPE = "Centos" ]; then
	echo "开始下载onigurma"
	download "https://libzip.org/download/libzip-${LIBZIP_VERSION}.tar.xz" "libzip-${LIBZIP_VERSION}.tar.xz" ${LIBZIP_MD5SUM}
	download "https://github.com/kkos/oniguruma/releases/download/v${ONIG_VERSION}${ONIG_VERSION_REV}/onig-${ONIG_VERSION}${ONIG_VERSION_REV}.tar.gz" "onig-${ONIG_VERSION}.tar.gz" ${ONIG_MD5SUM}
fi

download "https://cn2.php.net/distributions/php-${PHP_VERSION}.tar.xz" "php-${PHP_VERSION}.tar.xz" $PHP_MD5SUM
download https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz openssl-$OPENSSL_VERSION.tar.gz $OPENSSL_MD5SUM;
download "https://github.com/php-memcached-dev/php-memcached/archive/v${PHP_MEMCACHED_VER}.tar.gz" "php-memcached-${PHP_MEMCACHED_VER}.tar.gz" $PHP_MEMCACHED_MD5SUM

download "https://launchpad.net/libmemcached/1.0/${LIB_MEMCACHED_VER}/+download/libmemcached-${LIB_MEMCACHED_VER}.tar.gz"  "libmemcached-${LIB_MEMCACHED_VER}.tar.gz" $LIB_MEMCACHED_MD5SUM
download https://github.com/phpredis/phpredis/archive/${PHP_REDIS_VER}.tar.gz  phpredis-${PHP_REDIS_VER}.tar.gz $PHP_REDIS_MD5SUM

if [ ! -d "php-${PHP_VERSION}" ]; then
	tar -xvf php-$PHP_VERSION.tar.xz;
	pushd  php-$PHP_VERSION
	sed -i "s/freetype-config/pkg-config/g" ./configure
	sed -i "s/freetype-config/pkg-config/g" ./ext/gd/config.m4
	sed -i "s/FREETYPE2_CONFIG --cflags/FREETYPE2_CONFIG freetype2 --cflags/g" ./configure
	sed -i "s/FREETYPE2_CONFIG --libs/FREETYPE2_CONFIG freetype2 --cflags/g" ./configure
	popd
fi

if [ $OS_TYPE = "Centos" ]; then
	tar -xvf onig-$ONIG_VERSION.tar.gz
	pushd onig-$ONIG_VERSION
	if [ -f autogen.sh ]; then
		./autogen.sh
	fi
	./configure --prefix=/usr
	make -j${THREAD_NUM} && make install
	popd
fi

#Debian8 
if [ $OS_TYPE = "Debian" ]; then
	if [ $OS_VERSION = "811" ]; then
		download https://www.openssl.org/source/old/1.0.2/openssl-${POPENSSL_OLD_VERSION}.tar.gz  $OPENSSL_OLD_VERSION_MD5SUM
		
		if [ ! -d "openssl-${POPENSSL_OLD_VERSION}" ]; then tar -xvf openssl-${POPENSSL_OLD_VERSION}.tar.gz; fi

		pushd openssl-${POPENSSL_OLD_VERSION}
			./config --prefix=/usr
			make -j${THREAD_NUM} && make install
			cp openssl.pc /usr/lib/x86_64-linux-gnu/pkgconfig/openssl.pc
			pkg-config --modversion openssl
		popd
		
	fi
fi

if [ $OS_TYPE = "Centos" ]; then
	if [ ! -d "libzip-${LIBZIP_VERSION}" ]; then  tar -xvf phpredis-${LIBZIP_VERSION}.tar.gz; fi
	mkdir -p libzip-${LIBZIP_VERSION}/build
	pushd libzip-${LIBZIP_VERSION}/build
	cmake .. && make -j${THREAD_NUM} && make install
	popd
fi
if [ ! -d openssl-$OPENSSL_VERSION ]; then tar -xvf openssl-$OPENSSL_VERSION.tar.gz; fi

if [ ! -d "libmemcached-${LIB_MEMCACHED_VER}" ];then
	tar -xvf libmemcached-${LIB_MEMCACHED_VER}.tar.gz;
	sed -i 's/opt_servers == false/opt_servers == NULL/g' libmemcached-${LIB_MEMCACHED_VER}/clients/memflush.cc
fi

if [ ! -d "php-memcached-${PHP_MEMCACHED_VER}" ]; then  tar -xvf php-memcached-$PHP_MEMCACHED_VER.tar.gz; fi
if [ ! -d "phpredis-${PHP_REDIS_VER}" ]; then  tar -xvf phpredis-${PHP_REDIS_VER}.tar.gz; fi

pushd  php-$PHP_VERSION
if [ ! -f Makefile ];then
	#配置，MySql用的是mysqlnd
	if [ $OS_TYPE = "Debian" ]; then
		if [ $OS_VERSION = "81" ]; then
			export CC=gcc -g -o3 -std=c11
		fi
	fi
	./configure -prefix=${PHP8_BASE_PATH} \
		--disable-static \
		--enable-shared \
		--disable-debug \
		--enable-fpm \
		--enable-opcache \
		--with-fpm-user=php \
		--with-fpm-group=www \
		--with-config-file-path=${PHP8_BASE_PATH}/etc \
		--with-freetype=shared \
		--with-jpeg=shared \
		--with-zlib=shared \
		--disable-rpath \
		--enable-shmop \
		--enable-pcntl \
		--enable-mbregex \
		--enable-mbstring \
		--enable-gd --with-jpeg --with-webp --with-freetype \
		--enable-bcmath \
		--with-openssl=shared \
		--with-mhash=shared \
		--without-pear \
		--with-gettext=shared \
		--with-mysqli=mysqlnd \
		--with-pdo-mysql=mysqlnd \
		--enable-mysqlnd \
		--enable-sysvshm --enable-sysvmsg --enable-sysvsem \
		--with-pdo-mysql=shared
	#	--with-gmp=shared
	make -j${THREAD_NUM} && make install
#exit 0;
	pushd ext/opcache
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config && make clean && make -j${THREAD_NUM} && make install
	popd

	pushd ext/curl
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config &&  make clean && make -j${THREAD_NUM} && make install
	popd

	# PHPExcel 要用到
	pushd ext/zip
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config &&  make clean && make -j${THREAD_NUM} && make install
	popd


	pushd ext/gd
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config --with-freetype --with-jpeg --with-webp  &&  make clean && make -j${THREAD_NUM} && make install
	popd

	pushd ext/exif
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config &&  make clean && make -j${THREAD_NUM} && make install
	popd

	pushd ext/ftp
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config &&  make clean && make -j${THREAD_NUM} && make install
	popd

	pushd ext/openssl
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config &&  make clean && make -j${THREAD_NUM} && make install
	popd

	pushd ext/sockets
	${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config &&  make clean && make -j${THREAD_NUM} && make install
	popd
fi

pushd ../libmemcached-$LIB_MEMCACHED_VER
	./bootstrap.sh autoreconf
	./configure --enable-sasl
	make -j${THREAD_NUM} && make install
popd

pushd ../php-memcached-$PHP_MEMCACHED_VER
${PHP8_BASE_PATH}/bin/phpize && ./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config  --enable-memcached-json --enable-memcached-session --disable-memcached-sasl && make clean && make -j${THREAD_NUM} && make install
popd


pushd ../phpredis-${PHP_REDIS_VER}
	${PHP8_BASE_PATH}/bin/phpize && \
	./configure --with-php-config=${PHP8_BASE_PATH}/bin/php-config && make && make install
popd


# 拷贝配置文件
cp ${PHP8_BASE_PATH}/etc/php-fpm.conf.default ${PHP8_BASE_PATH}/etc/php-fpm.conf
cp ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf.default ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
cp php.ini-production ${PHP8_BASE_PATH}/etc/php.ini

# 修改默认配置
sed -i 's#listen = 127.0.0.1:9000#listen = /var/run/php/php8.1-fpm.sock#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#user = nobody#user = php#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#group = nobody#group = www#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf

sed -i 's#;listen.owner = [a-zA-Z0-9]+#listen.owner = php#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#;listen.group = [a-z]*#listen.group = www#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#;listen.mode = 0660#listen.mode = 0660#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf


sed -i 's#pm.max_children = [0-9]*#pm.max_children = 16#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#pm.start_servers = [0-9]*#pm.start_servers = 4#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#pm.min_spare_servers = [0-9]*#pm.min_spare_servers = 2#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#pm.max_spare_servers = [0-9]*#pm.max_spare_servers = 4#' ${PHP8_BASE_PATH}/etc/php-fpm.d/www.conf
sed -i 's#;error_log = log/php-fpm.log#error_log = /var/log/php-fpm.log#' ${PHP8_BASE_PATH}/etc/php-fpm.conf

# 修改php.ini 
sed -i 's#;date.timezone =#date.timezone = Asia/Shanghai#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;expose_php = On#expose_php = Off#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.enable=[0-9]*#opcache.enable=1#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;extension=exif#extension=exif.so#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;extension=pdo_mysql#extension=pdo_mysql.so#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;extension=gd2#extension=gd.so#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;extension=curl#extension=curl.so#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;extension=openssl#extension=openssl.so#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/;extension=soap/i\extension=memcached.so' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/;extension=soap/i\extension=sockets.so' ${PHP8_BASE_PATH}/etc/php.ini
#sed -i '/;extension=soap/i\extension=swoole.so' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/;extension=soap/i\extension=zlib.so' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/;extension=soap/i\extension=zip.so' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/;extension=soap/i\extension=ftp.so' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/;extension=soap/i\extension=redis.so' ${PHP8_BASE_PATH}/etc/php.ini


# opcache 开启
sed -i 's#;opcache.enable_cli=0#opcache.enable_cli=1#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.memory_consumption=[0-9]*#opcache.memory_consumption=512#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.file_cache=#opcache.file_cache=/dev/shm#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.huge_code_pages=[0-9]*#opcache.huge_code_pages=1#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.max_accelerated_files=[0-9]*#opcache.max_accelerated_files=100000#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.optimization_level=0x7FFFBFFF#opcache.optimization_level=0xFFFFFFFF#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;opcache.inherited_hack=1#opcache.inherited_hack=1#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#memory_limit = 128M#memory_limit = 512M#' ${PHP8_BASE_PATH}/etc/php.ini
sed -i '/memory_limit = 512M/a\zend_extension=opcache.so' ${PHP8_BASE_PATH}/etc/php.ini
sed -i 's#;     session.save_path = "N;/path"#session.save_path = "2;/tmp/phpsession"#' ${PHP8_BASE_PATH}/etc/php.ini

mkdir -p /var/run/php && chown -R php:www /var/run/php

cat <<EOF > ${PHP8_BASE_PATH}/sbin/initenv.sh
#!/bin/bash


if [ ! -d /var/run/php ]; then
	mkdir -p /var/run/php
	mkdir -p \${PHP8_BASE_PATH}/var
	chown -R php:www  /var/run/php ${PHP8_BASE_PATH}/var
fi

if [ ! -d /tmp/phpsession ]; then
	mkdir -p /tmp/phpsession
	rr=('0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' )
	for u in "\${rr[@]}"
	do
		for u1 in "\${rr[@]}"
		do
			mkdir -p "/tmp/phpsession/\${u}/\${u1}"
		done
	done

	chown -R php:www /tmp/phpsession
	chmod -R 0777 /tmp/phpsession
fi
exit 0
EOF

# 安装启动脚本
#cp sapi/fpm/php-fpm.service /lib/systemd/system/

chmod a+x ${PHP8_BASE_PATH}/sbin/initenv.sh

cat  <<EOF 	> /lib/systemd/system/php-fpm.service
# It's not recommended to modify this file in-place, because it
# will be overwritten during upgrades.  If you want to customize,
# the best way is to use the "systemctl edit" command.

[Unit]
Description=The PHP FastCGI Process Manager
After=network.target

[Service]
Type=simple
PIDFile=${PHP8_BASE_PATH}/var/run/php-fpm.pid
ExecStartPre=${PHP8_BASE_PATH}/sbin/initenv.sh
ExecStart=${PHP8_BASE_PATH}/sbin/php-fpm --nodaemonize --fpm-config ${PHP8_BASE_PATH}/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID

# Set up a new file system namespace and mounts private /tmp and /var/tmp directories
# so this service cannot access the global directories and other processes cannot
# access this service's directories.
PrivateTmp=false

# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by this unit.
ProtectSystem=full

# Sets up a new /dev namespace for the executed processes and only adds API pseudo devices
# such as /dev/null, /dev/zero or /dev/random (as well as the pseudo TTY subsystem) to it,
# but no physical devices such as /dev/sda.
PrivateDevices=true

# Explicit module loading will be denied. This allows to turn off module load and unload
# operations on modular kernels. It is recommended to turn this on for most services that
# do not need special file systems or extra kernel modules to work.
ProtectKernelModules=true

# Kernel variables accessible through /proc/sys, /sys, /proc/sysrq-trigger, /proc/latency_stats,
# /proc/acpi, /proc/timer_stats, /proc/fs and /proc/irq will be made read-only to all processes
# of the unit. Usually, tunable kernel variables should only be written at boot-time, with the
# sysctl.d(5) mechanism. Almost no services need to write to these at runtime; it is hence
# recommended to turn this on for most services.
ProtectKernelTunables=true

# The Linux Control Groups (cgroups(7)) hierarchies accessible through /sys/fs/cgroup will be
# made read-only to all processes of the unit. Except for container managers no services should
# require write access to the control groups hierarchies; it is hence recommended to turn this on
# for most services
ProtectControlGroups=true

# Any attempts to enable realtime scheduling in a process of the unit are refused.
RestrictRealtime=true

# Restricts the set of socket address families accessible to the processes of this unit.
# Protects against vulnerabilities such as CVE-2016-8655
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX

# Takes away the ability to create or manage any kind of namespace
RestrictNamespaces=true

[Install]
WantedBy=multi-user.target

EOF

systemctl enable php-fpm.service

popd
